package com.ruicar.afs.cloud.basic.sync;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.basic.common.entity.BasicChannelInfo;
import com.ruicar.afs.cloud.basic.common.entity.BasicMainInfo;
import com.ruicar.afs.cloud.basic.common.service.BasicChannelInfoService;
import com.ruicar.afs.cloud.basic.common.service.BasicMainInfoService;
import com.ruicar.afs.cloud.basic.proceeds.mq.dto.ContractChannelInfoDTO;
import com.ruicar.afs.cloud.basic.proceeds.mq.dto.ContractFinancialAgreementDTO;
import com.ruicar.afs.cloud.basic.proceeds.mq.dto.ContractMainInfoDTO;
import com.ruicar.afs.cloud.batch.entity.AfsBatchInfo;
import com.ruicar.afs.cloud.batch.enums.SystemStatus;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.modules.contract.enums.BusinessTypeEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.CollectionTypeEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.ContractStatusEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.text.MessageFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: Lee
 * @date: 2020/5/11 19:39
 * @description: 贷前数据同步-合同主信息、渠道类信息
 */
@AllArgsConstructor
@Component
@Slf4j
public class ApplyLoanDataChannelSubHandler{
	private final BasicMainInfoService mainInfoService;
	private final BasicChannelInfoService basicChannelInfoService;
	/*
	 * 合同激活前提条件公共校验
	 */
	public void validateOnBefore(AfsBatchInfo afsBatchInfo) {
		//验证切日是否完成
		if(afsBatchInfo==null){
			throw new AfsBaseException("获取日结信息失败，不能执行合同激活，请先处理完切日异常后再执行合同激活");
		}
		if(SystemStatus.NORMAL != afsBatchInfo.getSystemStatus()){
			throw new AfsBaseException("日结未正常关闭，不能执行合同激活，请先处理完切日异常后再执行合同激活");
		}
	}
	/*
	 * 合同激活之合同主表存储前校验
	 */
	public String validateOnSaveContractMain(ApplyLoanDataMessage entity) {
		String contractNo = "";
		ContractMainInfoDTO mainInfoDto = entity.getMainInfo();
		if(mainInfoDto==null || StringUtils.isEmpty(mainInfoDto.getContractNo())){
			throw new AfsBaseException("MQ消费合同主表为空或者合同编号为空，不能激活合同");
		}
		//校验合同系统是否存在同样合同编号的合同.
		int existContract = mainInfoService.count(
				Wrappers.<BasicMainInfo>lambdaQuery().eq(BasicMainInfo::getContractNo, mainInfoDto.getContractNo()));
		if(existContract > 0){
			//数据库已经存在记录，直接返回
			log.info("合同系统已经存在合同号{}的合同，直接返回",mainInfoDto.getContractNo());
			contractNo = mainInfoDto.getContractNo();
		}
		return contractNo;
	}
	/*
	 * 写入合同系统之合同主表
	 */
	public BasicMainInfo SaveContractMain(ApplyLoanDataMessage entity,Date batchDate) {
		//step3.1： copy 案件系统传递的数据
		ContractMainInfoDTO mainInfoDto = entity.getMainInfo();
		BasicMainInfo mainInfo = (BasicMainInfo) ApplyLoanDataProcessor.converBean(mainInfoDto, BasicMainInfo.class);
		//补丁一（渠道名称）
		mainInfo.setChannelFullName(mainInfoDto.getChannelName());
		// TODO 后续增加DEBUG下的执行模式，打印MQ的对象和转换后的对象中的空值
		ApplyLoanDataProcessor.getNullpropertyName(mainInfoDto);
		ApplyLoanDataProcessor.getNullpropertyName(mainInfo);

		//step3.2： 设置合同系统的属性 如： 合同状态，激活时间等
		mainInfo.setContractStatus(ContractStatusEnum.contractEffective);
		mainInfo.setStartDate(batchDate);
		mainInfoDto.setStartDate(batchDate);
		//车款和附件贷是分开的两个金融协议，故需要取两者中的最大的融资期限
		ContractFinancialAgreementDTO maxLoanTerm = entity.getFnancialAgreement().stream()
				.max(Comparator.comparing(ContractFinancialAgreementDTO::getLoanTerm)).get();
		//设置合同到期日，激活日期+最大贷期限 TODO 待余思俊确认逻辑
		mainInfo.setEndDate(DateUtil.offsetMonth(batchDate, maxLoanTerm.getLoanTerm())); // 通过最大贷款期限推算合同到期日
		// 设置还款日 TODO 待余思俊确认逻辑
		mainInfo.setRepaymentDate(String.valueOf(DateUtil.dayOfMonth(batchDate)));
		ContractChannelInfoDTO contractChannelInfoDTO=getContractChannelInfoDTO(entity);
		mainInfo.setChannelBelong(contractChannelInfoDTO.getChannelBelong());
		mainInfoService.save(mainInfo);
		return mainInfo;
	}
	/**
	 * 获取渠道收款账号信息
	 */
	public ContractChannelInfoDTO getContractChannelInfoDTO(ApplyLoanDataMessage entity){
		List<ContractChannelInfoDTO> channelInfoDto = entity.getChannelInfo();
		ContractMainInfoDTO mainInfo = entity.getMainInfo();
		if (ObjectUtils.isEmpty(channelInfoDto)) 	throw new AfsBaseException("[basic_channel_info] 渠道信息为空");
		channelInfoDto = channelInfoDto.stream()
				.filter(channelInfo -> channelInfo.getCollectionType() == CollectionTypeEnum.CAR_FUND
						&& mainInfo.getBusinessType() == channelInfo.getAccountAttribute())
				.collect(Collectors.toList());

		Assert.isTrue(!ObjectUtils.isEmpty(channelInfoDto),MessageFormat.format("未找到业务类型为:[{0}]的车款的收款账号", AfsEnumUtil.key(mainInfo.getBusinessType())));

		ContractChannelInfoDTO infoDto = channelInfoDto.get(0);
		return infoDto;
	}
	/**
	 * * 合同激活渠道类信息存储
	 */
	public BasicChannelInfo saveChannelInfo(ApplyLoanDataMessage entity){
		ContractMainInfoDTO mainInfo = entity.getMainInfo();
		List<ContractChannelInfoDTO> channelInfoDtos = entity.getChannelInfo();
		BasicChannelInfo basicChannelInfo = null;
		if (!ObjectUtils.isEmpty(channelInfoDtos)) {
			BusinessTypeEnum businessType = mainInfo.getBusinessType();
			//只保存车款账号,渠道信息只有一条
			channelInfoDtos = channelInfoDtos.stream()
					.filter(channelInfo -> channelInfo.getCollectionType() == CollectionTypeEnum.CAR_FUND && businessType == channelInfo.getAccountAttribute())
					.collect(Collectors.toList());
			if(ObjectUtils.isEmpty(channelInfoDtos)){
				throw new AfsBaseException("[basic_channel_info] 渠道车款收款账号为空");
			}
			List<BasicChannelInfo>  basicChannelInfoList = (List<BasicChannelInfo>) ApplyLoanDataProcessor.converBean(channelInfoDtos, BasicChannelInfo.class);

			basicChannelInfo = basicChannelInfoList.get(0);

			basicChannelInfoService.save(basicChannelInfo);
		} else {
			throw new AfsBaseException("[basic_channel_info] 渠道信息为空");
		}
		return basicChannelInfo;
	}
}
